package com.fenyin.samples.study.jdk.nio.channels.tcp.client;  

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.Iterator;
  
/**
 *@Author:fengzhichao  
 *@Since:2012-12-13  
 *@Version:1.1.0
 */
public class Client extends Thread{
	private CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
	private CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
	private Selector selector = null;
	private SocketChannel socketChannel = null;
	private int timeOut = 1;

	public Client(String ip,int port){
		try{
			//创建通道监听器
			selector = Selector.open();
			//创建Socket通道
			socketChannel = SocketChannel.open();
			//设置Socket通道为非阻塞模式
			socketChannel.configureBlocking(false);
			//Socket通道绑定通道监听器，事件集
			socketChannel.register(selector, SelectionKey.OP_CONNECT);
			//Socket通道连接到指定的服务端地址
			socketChannel.connect(new InetSocketAddress(ip,port));
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	public void run(){
		try{
			while(true){
				//选择一组做好准备IO操作的监听事件
				selector.select(timeOut);
				//获取监听事件
				Iterator<SelectionKey>it = selector.selectedKeys().iterator();
				//循环处理监听事件
				while(it.hasNext()){
					SelectionKey key = it.next();
					it.remove();
					if(key.isConnectable()){
						//连接事件处理
						if(socketChannel.isConnectionPending()){
							socketChannel.finishConnect();
						}
						socketChannel.register(selector, SelectionKey.OP_READ);
						System.out.println("连接服务器端成功！");
					}else if(key.isReadable()){
						ByteBuffer buffer = ByteBuffer.allocate(50);
						try{
							socketChannel.read(buffer);
						}catch(IOException e){
							System.out.println("与服务器："
									+ socketChannel.socket().getInetAddress().getHostName() + ":"
									+ socketChannel.socket().getPort() + "的连接已断开");
							socketChannel.close();
							continue;//这一句是为了让你看到打印信息
						}
						buffer.flip();
						String msg = decoder.decode(buffer).toString();
						System.out.println(
								socketChannel.socket().getInetAddress().getHostName() + ":"
								+ socketChannel.socket().getPort() + "：" + msg);
					}
				}
			}
   
		}catch(IOException e){
			e.printStackTrace();
		}
		finally{
			try{
				selector.close();
				socketChannel.close();
			}catch(IOException e){}
		}
	}

	public void send(String msg){
		try{
			socketChannel.write(encoder.encode(CharBuffer.wrap(msg)));
		}catch(Exception e){
			System.out.println("发送信息失败");
			e.printStackTrace();
		}
	}

	public void close(){
		try{
			selector.close();
			socketChannel.close();
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		Client client = new Client("localhost",19997);
		client.start();
		BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));
		try{
			String readline;
			while((readline = sin.readLine())!=null){
				if(readline.equals("bye")){
					client.close();
					System.exit(0);
				}
				client.send(readline);
			}
		}catch(IOException e){
			e.printStackTrace();
		}
	}
}
